package com.webxp.base;

import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;

import com.webxp.DB.DBMgr;
import com.webxp.util.Filter;

/**
 * 实体基类
 * 
 * @author hdg1988
 * 
 */
public class BaseObj implements Cloneable {

	private static org.apache.log4j.Logger logger = org.apache.log4j.Logger
			.getLogger("BaseObj.java");

	/**
	 * 构造函数
	 */
	public BaseObj(String _tableName, String _objIdName) {
		this.tableName = _tableName;
		this.objIdName = _objIdName;
	}

	/**
	 * 用来保存当前实例的属性名和值对
	 */
	private HashMap m_oAttrMap = new HashMap();
	private HashMap m_oColumnstype = new HashMap();
	/**
	 * 表名和ID字段名
	 */
	private String tableName = "";
	private String objIdName = "";

	public String getTableName() {
		return this.tableName;
	}

	/**
	 * 单个对象查找
	 * 
	 * @param _id
	 * @return
	 * @throws SQLException
	 */
	public Object _findById(int _id) throws SQLException {
		// 构造数据库查询语句
		Filter filter = new Filter("*", this.tableName, this.objIdName + "="
				+ _id, "");
		// 执行数据语句
		ResultSet set = filter.excureSQL();
		if (BaseSystem.isDebug) {
			logger.debug("方法名：_findById");
			logger.debug("SQL:" + filter.toString());
		}
		// 获取第一行
		if (!set.next())
			return null;
		// 获取列数
		int nColumns = set.getMetaData().getColumnCount();
		// 将属性添加到MAP中
		for (int i = 1; i <= nColumns; i++) {
			String sTypeName = set.getMetaData().getColumnTypeName(i);
			Object obj = set.getObject(i);
			String sColumnName = set.getMetaData().getColumnName(i);
			this.builtMap(sTypeName, sColumnName, obj);
		}
		// 返回
		return this;
	}

	/**
	 * 构造新实例
	 * 
	 * @param clazz
	 * @return
	 */
	public static BaseObj newInstance(Class clazz) throws Exception {
		if (clazz == null)
			throw new Exception("实例类不存在！");
		try {
			BaseObj newObj = (BaseObj) clazz.newInstance();
			newObj.initId();
			return newObj;
		} catch (Exception ex) {
			throw new Exception("创建实例对象失败！", ex);
		}
	}

	/**
	 * 根据数据类型构造MAP
	 * 
	 * @param _sType
	 * @param _sColumnName
	 * @param _obj
	 */
	public void builtMap(String _sType, String _sColumnName, Object _obj) {
		_sColumnName = _sColumnName.toUpperCase();
		m_oColumnstype.put(_sColumnName, _sType);
		if (_sType.equalsIgnoreCase(Types.DATABASE_TYPE_INT)) {
			// 整形
			m_oAttrMap.put(_sColumnName, (Integer) _obj);
		} else if (_sType.equalsIgnoreCase(Types.DATABASE_TYPE_VARCHAR)) {
			// 字符串
			m_oAttrMap.put(_sColumnName, (String) _obj);
		} else if (_sType.equalsIgnoreCase(Types.DATABASE_TYPE_DATETIME)) {
			// 时间
			m_oAttrMap.put(_sColumnName, (Date) _obj);
		} else if (_sType.equalsIgnoreCase(Types.DATABASE_TYPE_DATETIME)) {
			// 布尔
			m_oAttrMap.put(_sColumnName, (Boolean) _obj);
		}
	}

	/**
	 * 获取属性
	 * 
	 * @param _sAttrName
	 * @return
	 */
	public Object getAttribute(String _sAttrName) {
		_sAttrName = _sAttrName.toUpperCase();
		if (!this.m_oAttrMap.containsKey(_sAttrName))
			return null;
		return this.m_oAttrMap.get(_sAttrName);
	}

	/**
	 * 返回字符串属性
	 * 
	 * @param _sAttrName
	 * @return
	 */
	public String getAttributeAsString(String _sAttrName) {
		return (String) getAttribute(_sAttrName);
	}

	/**
	 * 返回整形属性
	 * 
	 * @param _sAttrName
	 * @return
	 */
	public int getAttributeAsInt(String _sAttrName) {
		return ((Integer) getAttribute(_sAttrName)).intValue();
	}

	/**
	 * 返回时间型属性
	 * 
	 * @param _sAttrName
	 * @return
	 */
	public Date getAttributeAsData(String _sAttrName) {
		return (Date) getAttribute(_sAttrName);
	}

	/**
	 * 返回布尔值属性
	 * 
	 * @param _sAttrName
	 * @return
	 */
	public boolean getAttributeAsBoolean(String _sAttrName) {
		return ((Boolean) getAttribute(_sAttrName)).booleanValue();
	}

	/**
	 * 设置对象的属性
	 * 
	 * @param _sAttrName
	 * @param _oAttrValue
	 */
	public void setAttribute(String _sAttrName, Object _oAttrValue) {
		_sAttrName = _sAttrName.toUpperCase();
		this.m_oAttrMap.put(_sAttrName, _oAttrValue);
	}

	/**
	 * 对象自保存
	 */
	public void save() {
		if (!isAddMode()) {
			update();
		} else {
			insert();
		}
	}

	/**
	 * 对象的更新
	 */
	public void update() {
		// 获取对象属性集合
		Iterator iter = this.m_oAttrMap.keySet().iterator();
		// 构造更新sql
		StringBuffer sql = new StringBuffer(128);
		sql.append("update ").append(this.tableName).append(" set ");
		while (iter.hasNext()) {
			String sKey = (String) iter.next();
			if (sKey.equalsIgnoreCase(objIdName))
				continue;
			// 获取该字段的类型
			sql.append(sKey).append("=").append(getAttrValueWithType(sKey));
			if (iter.hasNext())
				sql.append(",");
		}
		sql.append(" where ").append(this.objIdName).append("=").append(
				this.m_oAttrMap.get(this.objIdName.toUpperCase()));
		//日志记录
		if (BaseSystem.isDebug)
			logger.debug("SQL:" + sql);
		// 执行sql更新
		DBMgr.excure(sql.toString());
	}

	/**
	 * 往数据库中插入记录
	 */
	public void insert() {
		// 获取对象属性集合
		Iterator iter = this.m_oAttrMap.keySet().iterator();
		// 构造插入sql
		StringBuffer sql = new StringBuffer(128);
		sql.append("insert into ").append(this.tableName).append(" (");
		StringBuffer sValues = new StringBuffer(128);
		while (iter.hasNext()) {
			String sKey = (String) iter.next();
			if (sKey.equalsIgnoreCase(objIdName))
				continue;
			sql.append(sKey);
			sValues.append(getAttrValueWithType(sKey));
			if (iter.hasNext()) {
				sql.append(",");
				sValues.append(",");
			}
		}
		sql.append(") values (").append(sValues).append(")");
		if (BaseSystem.isDebug) {
			logger.debug("执行方法：insert");
			logger.debug("SQL:" + sql);
		}
		// 执行sql更新
		DBMgr.excure(sql.toString());

	}

	// TODO 如何获取到数据库中的列类型
	// TODO 判断这个列名是否存在
	private Object getAttrValueWithType(String _sColumnName) {
		String sType = (String) m_oColumnstype.get(_sColumnName);
		if (sType == null)
			return "'" + this.m_oAttrMap.get(_sColumnName) + "'";
		if (sType.equalsIgnoreCase(Types.DATABASE_TYPE_INT)
				|| sType.equalsIgnoreCase(Types.DATABASE_TYPE_BOOLEAN)
				|| sType.equalsIgnoreCase(Types.DATABASE_TYPE_DATETIME)) {
			return this.m_oAttrMap.get(_sColumnName);
		} else {
			return "'" + (String) this.m_oAttrMap.get(_sColumnName) + "'";
		}
	}

	/**
	 * 判断当前实例是否是属性新增模式
	 * 
	 * @return
	 */
	public boolean isAddMode() {
		if (((Integer) this.m_oAttrMap.get(objIdName)).intValue() > 0) {
			return false;
		}
		return true;
	}

	/**
	 * 构造新实例时，初始化ID
	 */
	public void initId() {
		if (this.m_oAttrMap.get(objIdName) != null)
			return;
		this.m_oAttrMap.put(objIdName, new Integer(0));
	}

	/**
	 * 获取当前实例的ID
	 * 
	 * @return
	 */
	public int getId() {
		return ((Integer) getAttribute(this.objIdName)).intValue();
	}
}
